#ifndef OS_DATA_TYPE_DEF__H__H
#define OS_DATA_TYPE_DEF__H__H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// #define OS_FOR_STM8
//#define OS_FOR_STM32
// #define MO_CHV32V30x
#define MO_CH58x

#ifdef MO_CHV32V30x
#include "debug.h"
#elif defined(OS_FOR_STM32)
//#include "cmsis_gcc.h"
#include "stm32f0xx_hal.h"
#elif defined(MO_CH58x)
#include "CH58x_common.h"
#else
#error "please to config a bsp module"
#endif

/*******@TODO need to define these, those depend on your IDE*/
//MO_CH58x
typedef int32_t mo_s32;
typedef short mo_s16;
typedef signed char mo_s8;
typedef uint32_t mo_u32;
typedef unsigned short mo_u16;
typedef unsigned char mo_u8;
//
/***************************************/

#define MAX_DELAY_MSG 70u
#define MAX_READY_MSG 30u
#define MO_VERSION    "V1.0.0"
#define MO_DEBUG_EN   0

#if MO_DEBUG_EN

#define MO_LOG(format, ...) \
  printf("[%s:%d]" format, __func__, __LINE__, ##__VA_ARGS__)
// printf("[%s:%d->%s]"format,__FILE__,__LINE__,__func__,##__VA_ARGS__)
#define mo_printf(format, ...) printf(format, ##__VA_ARGS__)
#define mo_printf_buf(buf,len) do{\
  int i;\
  for(i=0;i<(len);i++){\
      printf("%x ",(buf)[i]);\
  }\
  printf("\r\n");\
}while(0);

#else

#define MO_LOG(format, ...)
#define mo_printf(format, ...)

#endif

typedef enum {

    BTN_DOWN,
    BTN_UP,
    BTN_SINGLE_CLICK,
    BTN_MULTI_CLICK,
    BTN_LP,   /**long press**/
    BTN_VLP,  /**Very long press*/
    BTN_VVLP, /**Very very long press*/
    BTN_VVVLP,
    BTN_VVVVLP,

} mo_btn_pattern_t;

#define BTN_LOOP_INTERVAL 10ul /*mS**/
/*******@TODO: **********/
#if 1
#define MULTI_CLICK_TIMEOUT (400ul / BTN_LOOP_INTERVAL)   /**mS*/
#define BTN_LP_TIMEOUT      (1000ul / BTN_LOOP_INTERVAL)  /**mS*/
#define BTN_VLP_TIMEOUT     (3000ul / BTN_LOOP_INTERVAL)  /**mS*/
#define BTN_VVLP_TIMEOUT    (5000ul / BTN_LOOP_INTERVAL)  /**mS*/
#define BTN_VVVLP_TIMEOUT   (8000ul / BTN_LOOP_INTERVAL)  /**mS*/
#define BTN_VVVVLP_TIMEOUT  (10000ul / BTN_LOOP_INTERVAL) /**mS*/
#else
#define MULTI_CLICK_TIMEOUT 5ul   /**mS*/
#define BTN_LP_TIMEOUT      10ul  /**mS*/
#define BTN_VLP_TIMEOUT     30ul  /**mS*/
#define BTN_VVLP_TIMEOUT    50ul  /**mS*/
#define BTN_VVVLP_TIMEOUT   80ul  /**mS*/
#define BTN_VVVVLP_TIMEOUT  100ul /**mS*/
#endif
/****************************************************/
#define BTN_TIMING_TABLE                                                    \
  {                                                                         \
    MULTI_CLICK_TIMEOUT, BTN_LP_TIMEOUT, BTN_VLP_TIMEOUT, BTN_VVLP_TIMEOUT, \
        BTN_VVVLP_TIMEOUT, BTN_VVVVLP_TIMEOUT,                              \
  }

typedef enum {
  HW_KEY_NULL = 0,

  /******@TODO: Here to add/delete the Physical key you own on your
     product*************/
  HW_VOL_UP,
  HW_VOL_DOWN,
  HW_PW,
  HW_BT,
  HW_PLAY,
  /******************************************/

  HW_KEY_MAX   /***DO NOT MODIFI VK_CODE_MAX position in this enum**/
} mo_hw_key_t; /*Physical Key**/
#define HW_NUMBER_   (HW_KEY_MAX - 1)
#define VK_CODE_NULL HW_KEY_NULL
#define mo_vk_code_t mo_hw_key_t
// typedef enum {
//   VK_CODE_NULL = 0,

//   /******@TODO: Here to add/delete the virtual key you own on your
//      product*************/
//   VK_UP,
//   VK_DOWN,
//   VK_LEFT,
//   VK_RIGHT,
//   VK_SELECT,
//   /******************************************/

//   VK_CODE_MAX
// } mo_vk_code_t; /*Virtual Key**/

#if 0
/****The VK_TABLE need to config depend on you product******/
#define VK_TABLE_ \
  { VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_SELECT, }
#endif

/****@TODO: The INPUT_EVENT_MAP need to config depend on you product******/
#define INPUT_EVENT_MAP                                      \
  {                                                          \
    /*vk_code     btn_patt             event**/           \
    {HW_PW          , BTN_LP            , USR_EVENT_POWER_OFF },\
    {HW_PW          , BTN_LP            , USR_EVENT_POWER_ON },\
    {HW_VOL_UP      , BTN_SINGLE_CLICK  , USR_EVENT_MAIN_VOL_UP },\
    {HW_VOL_DOWN    , BTN_SINGLE_CLICK  , USR_EVENT_MAIN_VOL_DW },\
  }
/***********************************************************/

typedef struct {
    mo_hw_key_t vk_code;
    mo_btn_pattern_t vk_patt;
    mo_u8 click_num;
} mo_key_event_msg_t;

#include "mo_event.h"
#include "mo_mcu.h"

/*********************@TODO: ****************************************/
#define MCU_SLOT_SIZE 64ul /*a slot size in bytes*/
#define MAX_MCU_HEAP                                                          \
    (MCU_SLOT_SIZE * 20ul) /*define the maximum heap in byte, it must be less \
                              than or equal 2kB*/
#define MAX_MCU_SLOT          (MAX_MCU_HEAP / MCU_SLOT_SIZE)
#define MO_CRITICAL_ENTER()   mo_critical_enter()
#define MO_CRITICAL_EXIT(flg) mo_critical_exit(flg)
#define MO_GET_TICK()         mo_get_tick()
#define MO_TICK_TIMER_INIT()  mo_1ms_timer_nit()
#define MO_FORCE_SYS_RESET()  mo_reset_mcu()
#define MO_OS_SLEEP(time)     _sleep(time) /***Only for window demo**/
/***************************************************************************/

//#include "mo_heap.h"
//#include "mo_list.h"
//#include "mo_msg.h"
//#include "mo_button.h"

#endif
